#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
排班监控集成示例
展示如何将排班监控工具集成到三班制排班接口中
"""

import threading
import time
from typing import Dict, Any, Optional

from app.schedule_progress import ScheduleMonitor
from app.three_shift import auto_schedule
from config_params import three_shift_params


# 全局监控器实例
_monitor = None
_monitor_lock = threading.Lock()


def get_monitor() -> ScheduleMonitor:
    """
    获取排班监控器实例（单例模式）
    
    Returns:
        ScheduleMonitor: 排班监控器实例
    """
    global _monitor
    
    with _monitor_lock:
        if _monitor is None:
            auto_schedule_minutes = three_shift_params.get("auto_schedule_minutes", 7)
            _monitor = ScheduleMonitor(auto_schedule_minutes=auto_schedule_minutes)
    
    return _monitor


def start_monitor():
    """启动排班监控器"""
    monitor = get_monitor()
    monitor.start_monitor()
    print(f"排班监控器已启动，自动排班间隔: {monitor.auto_schedule_minutes}分钟")


def stop_monitor():
    """停止排班监控器"""
    global _monitor
    
    with _monitor_lock:
        if _monitor is not None:
            _monitor.stop_monitor()
            _monitor = None
    
    print("排班监控器已停止")


def get_monitor_status() -> Dict[str, Any]:
    """
    获取排班监控器状态
    
    Returns:
        Dict[str, Any]: 监控器状态信息
    """
    monitor = get_monitor()
    return monitor.get_status()


def monitored_auto_schedule() -> Dict[str, Any]:
    """
    带监控的自动排班函数
    
    Returns:
        Dict[str, Any]: 排班结果
    """
    monitor = get_monitor()
    
    # 开始排班
    monitor.start_scheduling(total_steps=200)
    
    # 创建进度更新线程
    progress_thread = None
    stop_progress = threading.Event()
    
    def update_progress():
        current = 0
        while not stop_progress.is_set():
            # 模拟算法进度
            current = min(current + 1, 199)  # 最大到199，留一步给最终结果
            monitor.update_progress(current, f"算法优化中 {current}/200")
            time.sleep(0.1)
    
    try:
        # 启动进度更新线程
        progress_thread = threading.Thread(target=update_progress)
        progress_thread.daemon = True
        progress_thread.start()
        
        # 执行实际排班
        result = auto_schedule()
        
        # 停止进度更新
        stop_progress.set()
        if progress_thread:
            progress_thread.join(timeout=1)
        
        # 更新最终进度
        monitor.update_progress(200, "排班完成")
        
        # 通知监控器排班完成
        monitor.finish_scheduling(result)
        
        return result
    
    except Exception as e:
        # 发生异常时停止进度更新
        stop_progress.set()
        if progress_thread:
            progress_thread.join(timeout=1)
        
        # 通知监控器排班失败
        monitor.finish_scheduling({"success": False, "error": str(e)})
        
        # 重新抛出异常
        raise


# 简单使用示例
if __name__ == "__main__":
    from app import create_app
    
    # 启动监控器
    start_monitor()
    
    try:
        # 等待10秒
        print("等待10秒...")
        time.sleep(10)
        
        # 执行带监控的自动排班
        print("开始排班...")
        with create_app().app_context():
            result = monitored_auto_schedule()
            print(f"排班结果: {result}")
        
        # 再等待10秒
        print("再等待10秒...")
        time.sleep(10)
        
    except KeyboardInterrupt:
        print("用户中断")
    finally:
        # 停止监控器
        stop_monitor()
